package com.sdhs.paas.itims.app;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sdhs.paas.itims.bean.ItimsTerminalBean;
import com.sdhs.paas.itims.bean.ItmsReportHistoryBean;
import com.sdhs.paas.itims.bean.VersionPublishDetailBean;
import com.sdhs.paas.itims.common.msg.BaseResponse;
import com.sdhs.paas.itims.configuration.Config;
import com.sdhs.paas.itims.dto.DeviceDTO;
import com.sdhs.paas.itims.dto.DeviceOperationDTO;
import com.sdhs.paas.itims.dto.DeviceReportDTO;
import com.sdhs.paas.itims.dto.DeviceResultDTO;
import com.sdhs.paas.itims.dto.DeviceUpgradeDTO;
import com.sdhs.paas.itims.dto.req.DeviceOperationReqDTO;
import com.sdhs.paas.itims.dto.req.DeviceReqDTO;
import com.sdhs.paas.itims.dto.req.DeviceUpgradeReqDTO;
import com.sdhs.paas.itims.dto.res.DeviceOperationResDTO;
import com.sdhs.paas.itims.dto.res.DeviceResDTO;
import com.sdhs.paas.itims.dto.res.DeviceResultReqDTO;
import com.sdhs.paas.itims.service.ItimsTerminalService;
import com.sdhs.paas.itims.service.ItmsReportHistoryService;
import com.sdhs.paas.itims.service.VersionPublishDetailService;
import com.sdhs.paas.sdk.core.PaasBaseException;
import com.sdhs.paas.sdk.core.PaasBaseRequest;
import com.sdhs.paas.sdk.core.PaasBaseResponse;
import com.sdhs.paas.sdk.core.RefreshableRestController;
import com.sdhs.paas.sdk.core.logger.Logger;
import com.sdhs.paas.sdk.core.logger.LoggerFactory;
import com.sdhs.paas.sdk.core.web.client.PaasRestTemplate;

@RefreshableRestController
@RequestMapping(value = "/pos")
public class ItimsPosExchangeController {
	
	private static Logger LOGGER  = LoggerFactory.getLogger(ItimsPosExchangeController.class); 
	
	@Autowired
	PaasRestTemplate paasRestTemplate;
	
	@Autowired
	@Qualifier("externalRestTemplate")
	private PaasRestTemplate externalRestTemplate;  
	
	@Autowired
	Config config;
	
	@Autowired
    private ItimsTerminalService itimsTerminalService;
	
	@Autowired
    private VersionPublishDetailService versionPublishDetailService;
	
	@Autowired
    private ItmsReportHistoryService itmsReportHistoryService;
		
	/**
	 * 获取终端状态接口
	 * @throws JsonProcessingException 
	 */
	@PostMapping("/health")
	public PaasBaseResponse<DeviceResDTO> health(@RequestBody PaasBaseRequest<DeviceReqDTO> devicePaasReqDTO) throws JsonProcessingException {
		DeviceDTO deviceDTO = devicePaasReqDTO.getBody().getDeviceDTO();
		DeviceReqDTO deviceReqDTO = new DeviceReqDTO();
		List<String> device_id = new ArrayList<String>();
		device_id.add(deviceDTO.getDevice_id());
		String[] strings = new String[device_id.size()];
		strings = device_id.toArray(strings);
		ObjectMapper mapper = new ObjectMapper();
		deviceReqDTO.setDevice_id(device_id.toArray(strings));
		String jsonStr = mapper.writeValueAsString(deviceReqDTO);
		ModelMap objRest = null;
		try{
		objRest = externalRestTemplate.postForObject(config.nettyServerUrl+"/api/pos/health", deviceReqDTO, ModelMap.class);
		}catch(Exception e){
			DeviceResDTO deviceResDTO = new DeviceResDTO();
			deviceDTO.setHealth(false);
			deviceDTO.setAddress("山东高速集团");
			deviceDTO.setDevice_id("123456");
			deviceDTO.setLasttime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
			deviceDTO.setLongitude("117.124966");
			deviceDTO.setLatitude("36.653123");
			deviceResDTO.setDeviceDTO(deviceDTO);
			return new PaasBaseResponse<>(deviceResDTO);
		}
		List<Map<String,Object>> deviceList = (List<Map<String, Object>>) objRest.get("data");
		if(deviceList != null && deviceList.size() == 1){
			Map<String,Object> map = deviceList.get(0);
			deviceDTO.setDevice_id(map.get("device_id")+"");
			deviceDTO.setHealth(Boolean.valueOf(map.get("health")+""));
			deviceDTO.setLasttime(map.get("lasttime")+"");
			deviceDTO.setLongitude(map.get("longitude")+"");
			deviceDTO.setLatitude(map.get("latitude")+"");
			deviceDTO.setAddress(map.get("address")+"");
			deviceDTO.setPrinter_status(map.get("printer_status")+"");
		}else{
			deviceDTO = new DeviceDTO();
			deviceDTO.setHealth(false);
		}
		DeviceResDTO deviceResDTO = new DeviceResDTO();
		deviceResDTO.setDeviceDTO(deviceDTO);
		return new PaasBaseResponse<>(deviceResDTO);
	}
	
	/**
	 * 下发命令——升级POS机程序
	 * @throws JsonProcessingException 
	 */
	@PostMapping("/upgrade")
	public PaasBaseResponse<DeviceResDTO> upgrade(@RequestBody PaasBaseRequest<DeviceUpgradeReqDTO> deviceUpgradeReqDTO) throws JsonProcessingException {
		DeviceUpgradeDTO deviceUpgradeDTO = deviceUpgradeReqDTO.getBody().getData();
//		String device_id = "123456";
//		String url = "http://apk.xlpayment/file/pos-v3.3.3.apk";
//		String hashcode = "72141430A1452631EA9213DF68F6453D";
//		String version = "V2.2.2";
		String device_id = deviceUpgradeDTO.getDevice_id();
		String url = deviceUpgradeDTO.getUrl();
		String hashcode = deviceUpgradeDTO.getHashcode();
		String version = deviceUpgradeDTO.getVersion();
		DeviceUpgradeReqDTO duDTO = new DeviceUpgradeReqDTO();
		duDTO.setDevice_id(device_id);
		deviceUpgradeDTO = new DeviceUpgradeDTO();
		deviceUpgradeDTO.setUrl(url);
		deviceUpgradeDTO.setHashcode(hashcode);
		deviceUpgradeDTO.setVersion(version);
		duDTO.setData(deviceUpgradeDTO);
		ObjectMapper mapper = new ObjectMapper();
		String jsonStr = mapper.writeValueAsString(duDTO);
		ModelMap objRest = null;
		try{
			objRest = externalRestTemplate.postForObject(config.nettyServerUrl+"/api/pos/version", duDTO, ModelMap.class);
		}catch(Exception e){
			throw new PaasBaseException("500", "调用nettyserver升级接口失败！");
		}
		String code = objRest.get("code")+"";
		String msg = objRest.get("objRest")+"";
		DeviceResDTO deviceResDTO = new DeviceResDTO();
		if("0000".equals(code)){
			
		}else if("9999".equals(code)){
			
		}else{
			throw new PaasBaseException("500",msg);
		}
		return new PaasBaseResponse<>(deviceResDTO);
	}
	
	/**
	 * 上传命令——升级POS机程序返回结果
	 */
	@PostMapping("/result")
	public BaseResponse result(@RequestBody DeviceResultReqDTO deviceResultReqDTO) {
		String deviceId = deviceResultReqDTO.getDevice_id();
		DeviceResultDTO deviceResultDTO= deviceResultReqDTO.getData(); 
		String step = deviceResultDTO.getStep();
		String new_version = deviceResultDTO.getNew_version();
		String res_code = deviceResultDTO.getRes_code();
		String res_desc = deviceResultDTO.getRes_desc();
		VersionPublishDetailBean versionPublishDetailBean = new VersionPublishDetailBean();
		versionPublishDetailBean.setEquipmentSyn(deviceId);
		versionPublishDetailBean.setStatus(Integer.parseInt(step));
		versionPublishDetailBean.setRemark(new_version);
		/**
		 * 根据设备id和版本号，将查询到的记录全部更新了，注意：传参时使用remark来传递版本参数。
		 * 根据设备id和版本号无法确定一条记录，所以更新是有可能会更新多条，这个逻辑可能会存在问题
		 * 建议发布时一个版本不要连续发布多次
		 * */
		Boolean flag = versionPublishDetailService.updatePosReportStataus(versionPublishDetailBean);
		ItmsReportHistoryBean itmsReportHistoryBean = new ItmsReportHistoryBean();
		itmsReportHistoryBean.setEquipmentId(deviceId);
		itmsReportHistoryBean.setType("1");
		itmsReportHistoryBean.setTypeName("升级上报");
		itmsReportHistoryBean.setResult(step);
		itmsReportHistoryBean.setRemark("1:接收升级命令；2：文件下载成功；3：升级完成");
		//保存上报信息
		flag = saveReportHistory(itmsReportHistoryBean);
		BaseResponse res = new BaseResponse();
		res.setCode("0000");
		res.setMsg("success");
		LOGGER.info("终端序列号:"+deviceId+"-版本："+new_version+"-上报成功"+flag);
//		if(flag){
//			res.setCode("0000");
//			res.setMsg("success");
//			LOGGER.info("终端序列号:"+deviceId+"-版本："+new_version+"-上报成功");
//		}else{
//			res.setCode("9999");
//			res.setMsg("异常信息");
//			LOGGER.info("终端序列号:"+deviceId+"-版本："+new_version+"-上报失败");
//		}
//		
		return res;
	}
	
	/**
	 * 终端上报自动入库
	 * 设备硬件序列号、设备型号、设备厂商、系统版本上报，然后入库
	 */
	@PostMapping("/report")
	public BaseResponse report(@RequestBody DeviceReportDTO deviceReportDTO) {
		BaseResponse res = new BaseResponse();
		String deviceId = deviceReportDTO.getDevice_id();//硬件序列号
		String device_type = deviceReportDTO.getDevice_type();//设备类型
		String device_customer = deviceReportDTO.getDevice_customer();//终端厂家
		String device_version = deviceReportDTO.getDevice_version();//终端版本
		String trans_sn = deviceReportDTO.getTrans_sn();//业务终端号
		String biz_sn = deviceReportDTO.getBiz_sn();//交易终端号
		String iccid = deviceReportDTO.getIccid();
		String app_version = deviceReportDTO.getApp_verison();//应用版本号
		ItimsTerminalBean itimsTerminalBean  = new ItimsTerminalBean();
		itimsTerminalBean.setEquipmentId(deviceId);
		itimsTerminalBean.setIsDeleted(0);
		//如果终端设备已经存储到数据库里
		List<ItimsTerminalBean> list = itimsTerminalService.getList(itimsTerminalBean);
		Boolean flag = true;//更新或新增成功与否的标识
		//如果数据库里面已经存在终端信息，就更新终端的online=1，并且更新gmtmodified_time=now()
		if(list.size() > 0 ){
			itimsTerminalBean = list.get(0);
			itimsTerminalBean.setOnline(1);
			itimsTerminalBean.setAppVersion(app_version);
			flag = itimsTerminalService.updateItimsTerminal(itimsTerminalBean);
			if(flag){
				res.setCode("0000");
				res.setMsg("success");
			}else{
				res.setCode("9999");
				res.setMsg("终端信息更新数据库状态失败！");
				LOGGER.info(deviceId+"终端信息保存数据库失败！");
			}
			LOGGER.info("数据库已经存在终端信息！终端号："+deviceId+";应用版本:"+app_version);
			return res;
		}
		String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
		itimsTerminalBean.setId(uuid);
		itimsTerminalBean.setIccid(iccid);
		itimsTerminalBean.setEquipmentType(device_type);
		itimsTerminalBean.setEquipmentPro(device_customer);
		itimsTerminalBean.setRemark(device_version);
		itimsTerminalBean.setEquipmentNo(trans_sn);//交易终端号
		itimsTerminalBean.setImeiNo(biz_sn);//业务终端号
		itimsTerminalBean.setOnline(1);
		itimsTerminalBean.setAppVersion(app_version);
		/**
		 *  终端主动上报一次，先判断终端是否记录到数据库里，如果已经记录就告诉终端上报成功了。
			如果没有记录到数据库里，就执行sql保存数据库里。
			如果保存成功，就返回终端上报成功
			如果保存失败，就返回给终端上报失败
			终端隔一段时间上报一次或者人来操作终端上报。
		 * */
		flag = itimsTerminalService.saveItimsTerminal(itimsTerminalBean);
		if(flag){
			res.setCode("0000");
			res.setMsg("success");
		}else{
			res.setCode("9999");
			res.setMsg("终端信息保存数据库失败！");
			LOGGER.info("终端信息保存数据库失败！");
		}
		return res;
	}
	
	
	
	
	/**
	 * 下发终端升级和重启的命令
	 */
	@PostMapping("/posOperations")
	public DeviceOperationResDTO posOperationsReport(@RequestBody PaasBaseRequest<DeviceOperationReqDTO> deviceOperationReqDTO) {
		DeviceOperationDTO deviceOperationDTO = deviceOperationReqDTO.getBody().getData();
		String device_id= deviceOperationDTO.getDevice_id(); 
		String type = deviceOperationDTO.getType();
		LOGGER.info("终端序列号:"+device_id+"-指令："+type+"-下发关机(0)或重启指令(1)");
		ModelMap objRest = null;
		try{
			objRest = externalRestTemplate.postForObject(config.nettyServerUrl+"/api/pos/system/control", deviceOperationDTO, ModelMap.class);
		}catch(Exception e){
			throw new PaasBaseException("500", "调用nettyserver下发指令失败！");
		}
		String code = objRest.get("code")+"";
		String msg = objRest.get("msg")+"";
		DeviceOperationResDTO deviceOperationResDTO = new DeviceOperationResDTO();
		if("0000".equals(code)){
			LOGGER.info("终端序列号:"+device_id+"下发指令成功！");
		}else if("9999".equals(code)){
			LOGGER.info("终端序列号:"+device_id+"下发指令失败！");
			throw new PaasBaseException("000000","调用nettyserver下发指令失败！");
		}else{
			throw new PaasBaseException("500",msg);
		}
		
		return deviceOperationResDTO;
	}
	
	/**
	 * 收集终端关机和重启上报的信息
	 */
	@PostMapping("/posOperationsReport")
	public BaseResponse posOperations(@RequestBody DeviceOperationReqDTO deviceOperationReqDTO) {
		String deviceId = deviceOperationReqDTO.getDevice_id();
		DeviceOperationDTO deviceOperationDTO= deviceOperationReqDTO.getData(); 
		String type = deviceOperationDTO.getType();
		String res_code = deviceOperationDTO.getRes_code();
		String res_desc = deviceOperationDTO.getRes_desc();
		LOGGER.info("终端序列号:"+deviceId+"-上报指令："+type+"-状态码"+res_code+"-状态描述"+res_desc);	
		//记录终端关机或重启上报的响应信息
		ItmsReportHistoryBean itmsReportHistoryBean = new ItmsReportHistoryBean();
		itmsReportHistoryBean.setEquipmentId(deviceId);
		itmsReportHistoryBean.setType(type);
		String typeName = "";
		if("0".equals(type)){
			typeName = "关机上报";
		}else{
			typeName = "重启上报";
		}
		itmsReportHistoryBean.setTypeName(typeName);
		itmsReportHistoryBean.setResult(res_code);
		itmsReportHistoryBean.setRemark(res_desc);
		//保存上报信息
		boolean flag = saveReportHistory(itmsReportHistoryBean);
		//记录到上报日志表里，此处只是记录到日志文件中
		BaseResponse res = new BaseResponse();
		res.setCode("0000");
		res.setMsg("success");
		return res;
	}
	
	private Boolean saveReportHistory(ItmsReportHistoryBean itmsReportHistoryBean){
		String uuid = UUID.randomUUID().toString().trim().replaceAll("-", "");
		itmsReportHistoryBean.setId(uuid);
		itmsReportHistoryBean.setIsDeleted(0);
		return itmsReportHistoryService.saveItmsReportHistory(itmsReportHistoryBean);
	}
	
}
